#ifndef CFG_HPP
#define	CFG_HPP

#include <set>
#include "ast.hpp"
#include "cfg_visitor.hpp"
using namespace std;
class CFGvisitor;
class CFGvertex;
class ASTnode;
class atomic_statement;
class bexp;


class CFGedge {
public:
	CFGedge(CFGvertex *_src);
	CFGvertex*	getSource() const;
	CFGvertex*	getDestination() const;
	void		setDestination(CFGvertex *dest);
private:
	CFGvertex* const src;	// Pointer must not be re-seated
	CFGvertex* dst;
};


class CFGvisitable {
public:
	int visited;
	CFGvisitable();
	virtual void acceptVisit(CFGvisitor *visitor) = 0;
};

	typedef vector<const CFGedge*> outgoing_t;

class CFGvertex : public dotable, public CFGvisitable, public counter<CFGvertex> {
public:
	typedef set<CFGedge*> incoming_t;
	incoming_t incoming_edges() const;
	virtual outgoing_t outgoing_edges() const = 0;
	friend void CFGedge::setDestination(CFGvertex *dest);
	int label() const;
private:
	incoming_t incoming;
};

class box : public CFGvertex {
public:
	box();
	void acceptVisit(CFGvisitor *visitor);
	outgoing_t outgoing_edges() const;
	ASTnode *payload;
	CFGedge child;
};

class diamond : public CFGvertex {
public:
	diamond();
	void acceptVisit(CFGvisitor *visitor);
	outgoing_t outgoing_edges() const;
	bexp *condition;
	CFGedge true_branch;
	CFGedge false_branch;
};

#endif	/* CFG_HPP */
